
#include <io.h>


template <typename T>
class Grid
{
    public:
        //The general-purpose Grid allows the user to specify its dimensiions
        Grid(size_t inWidth = kDefaultWidth, size_t inHeight = kDefaultHeight);
        Grid(const Grid<T>& src);   //copy constructor
        virtual ~Grid();

        Grid<T>& operator=(const Grid<T>& rhs); //assignment operator
        void setElementAt(size_t x,size_t y,const T& inPiece);
        T& getElementAt(size_t x,size_t y);
        const T& getElementAt(size_t x,size_t y) const;

        size_t getHeight() const {return mHeight;}
        size_t getWidth() const {return  mWidth;}

        static const size_t kDefaultWidth = 10;
        static const size_t kDefaultHeight = 10;

    protected:
        void copyFrom(const Grid<T>& src);
        //objects dynamicaly allocate space for the game pieces.
        T** mCells;
        size_t mWidth,mHeight;
};

//模板要求将方法的实现也放在头文件本身中，因为编译器在创建模板的实例之前
//需要知道完整的定义，包括方法的定义。

template <typename T>
Grid<T>::Grid(size_t inWidth,size_t inHeight) : mWidth(inWidth),
mHeight(inHeight)
{
    mCells = new T* [mWidth];
	for (size_t i = 0; i < mWidth; i++) {
		mCells[i] = new T[mHeight];
	}
}


template <typename T>
Grid<T>::Grid(const Grid<T>& src)
{
    copyFrom(src);
}

template<typename T>
Grid<T>::~Grid()
{
    //free the old memory
    for(size_t i = 0; i < mWidth;i++){
        delete [] mCells[i];
    }
    delete [] mCells;
    mCells = nullptr;
}

template <typename T>
void Grid<T>::copyFrom(const Grid<T>& src)
{
    mWidth = src.mWidth;
    mHeight = src.mHeight;

    mCells = new T* [mWidth];
    for(size_t i = 0; i < mWidth;i++){
        mCells[i] new T[mHeight];
    }

    for(size_t i = 0;i < mWidth;i++){
        for(size_t j = 0; j < mHeight;j++){
            mCells[i][j] = src.mCells[i][j];
        }
    }
}


template <typename T>
Grid<T>& Grid<T>::operator=(const Grid<T>& rhs)
{
    //check for self-assignment
    if(this == &rhs){
        return *this;
    }
    //free the old memory
    for(size_t i = 0; i < mWidth;i++){
        delete [] mCells[i];
    }
    delete [] mCells;
    mCells = nullptr;

    //copy the new memory
    copyFrom(rhs);
    return *this;
}

template <typename T>
void Grid<T>::setElementAt(size_t,size_t y,const T& inElem)
{
    mCells[x][y] = inElem;
}

template <typename T>
T& Grid<T>::getElementAt(size_t x,size_t y)
{
    return memccpy[x][y]
}

template <typename T>
const T& Grid<T>::getElementAt(size_t x,size_t y) const{
    return mCells[x][y];
}
